{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hiding Images in Plain Sight: Deep Steganography \n",
    "\n",
    "#### An Unofficial Tensorflow Implementation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "%pylab inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import glob\n",
    "import os\n",
    "from PIL import Image,ImageOps\n",
    "import random\n",
    "import tensorflow as tf\n",
    "import time\n",
    "from datetime import datetime\n",
    "from os.path import join"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configuration\n",
    "All Configuration related information is represented in CAPS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "TRAIN_PATH = './data/train/'\n",
    "LOGS_Path = \"./logs/\"\n",
    "CHECKPOINTS_PATH = './checkpoints/'\n",
    "\n",
    "\n",
    "BATCH_SIZE = 8\n",
    "LEARNING_RATE = .0001\n",
    "BETA = .75\n",
    "\n",
    "EXP_NAME = f\"beta_{BETA}\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Helper Methods to Handle images \n",
    "The images are first converted to float values between 0 and 1. \n",
    "\n",
    "Then they are normalised using the Mean and STD from ImageNet. \n",
    "\n",
    "To convert these normalised values back to images, a helper function to undo this normalisation is also written."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "files_list = glob.glob(join(TRAIN_PATH,\"**/*\"))\n",
    "\n",
    "def normalize_batch(imgs):\n",
    "    return (imgs -  np.array([0.485, 0.456, 0.406])) /np.array([0.229, 0.224, 0.225])\n",
    "                                                        \n",
    "def denormalize_batch(imgs,should_clip=True):\n",
    "    imgs= (imgs * np.array([0.229, 0.224, 0.225])) + np.array([0.485, 0.456, 0.406])\n",
    "    \n",
    "    if should_clip:\n",
    "        imgs= np.clip(imgs,0,1)\n",
    "    return imgs\n",
    "\n",
    "def get_img_batch(files_list,batch_size=32,size=(224,224),should_normalise=True):\n",
    "   \n",
    "    batch_cover = []\n",
    "    batch_secret = []\n",
    "\n",
    "    for i in range(batch_size):\n",
    "        img_secret_path = random.choice(files_list)\n",
    "        img_cover_path = random.choice(files_list)\n",
    "        \n",
    "        img_secret = Image.open(img_secret_path).convert(\"RGB\")\n",
    "        img_cover = Image.open(img_cover_path).convert(\"RGB\")\n",
    "\n",
    "        img_secret = np.array(ImageOps.fit(img_secret,size),dtype=np.float32)\n",
    "        img_cover = np.array(ImageOps.fit(img_cover,size),dtype=np.float32)\n",
    "        \n",
    "        img_secret /= 255.\n",
    "        img_cover /= 255.\n",
    "        \n",
    "        batch_cover.append(img_cover)\n",
    "        batch_secret.append(img_secret)\n",
    "        \n",
    "    batch_cover,batch_secret = np.array(batch_cover) , np.array(batch_secret)\n",
    "    \n",
    "    if should_normalise:\n",
    "        batch_cover = normalize_batch(batch_cover)\n",
    "        batch_secret = normalize_batch(batch_secret)\n",
    "\n",
    "    return batch_cover,batch_secret\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network Definitions\n",
    "The three networks are identical in terms of structure. \n",
    "\n",
    "1. The Prepare network takes in the **Secret Image** and outputs a (BATCH_SIZE,INPUT_HEIGHT,INPUT_WEIGHT,150) tensor. \n",
    "\n",
    "2. The Cover network takes in the output from 1. , and a *Cover Image*. It concatenates these two tensors , giving a (BATCH_SIZE,INPUT_HEIGHT,INPUT_WEIGHT,153) tensor. Then it performs Convolutions , and outputs a (BATCH_SIZE,INPUT_HEIGHT,INPUT_WEIGHT,3) image.\n",
    "\n",
    "3. The Reveal Network Takes in the output image from Cover Network , and outputs the Revealed Image (which is supposed to look like the **Secret Image**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_prep_network_op(secret_tensor):\n",
    "    \n",
    "    with tf.variable_scope('prep_net'):\n",
    "        \n",
    "        with tf.variable_scope(\"3x3_conv_branch\"):\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=secret_tensor,filters=50,kernel_size=3,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"2\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        with tf.variable_scope(\"4x4_conv_branch\"):\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=secret_tensor,filters=50,kernel_size=4,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"2\",activation=tf.nn.relu)           \n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "\n",
    "        with tf.variable_scope(\"5x5_conv_branch\"):\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=secret_tensor,filters=50,kernel_size=5,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"2\",activation=tf.nn.relu)           \n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        concat_1 = tf.concat([conv_3x3,conv_4x4,conv_5x5],axis=3,name='concat_1')\n",
    "        \n",
    "        conv_5x5 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=5,padding='same',name=\"final_5x5\",activation=tf.nn.relu)\n",
    "        conv_4x4 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=4,padding='same',name=\"final_4x4\",activation=tf.nn.relu)\n",
    "        conv_3x3 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=3,padding='same',name=\"final_3x3\",activation=tf.nn.relu)\n",
    "        \n",
    "        concat_final = tf.concat([conv_5x5,conv_4x4,conv_3x3],axis=3,name='concat_final')\n",
    "\n",
    "        return concat_final\n",
    "\n",
    "    \n",
    "def get_hiding_network_op(cover_tensor,prep_output):\n",
    "    \n",
    "    with tf.variable_scope('hide_net'):\n",
    "        concat_input = tf.concat([cover_tensor,prep_output],axis=3,name='images_features_concat')\n",
    "        \n",
    "        with tf.variable_scope(\"3x3_conv_branch\"):\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=concat_input,filters=50,kernel_size=3,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"2\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        with tf.variable_scope(\"4x4_conv_branch\"):\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=concat_input,filters=50,kernel_size=4,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"2\",activation=tf.nn.relu)          \n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "\n",
    "        with tf.variable_scope(\"5x5_conv_branch\"):\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=concat_input,filters=50,kernel_size=5,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"2\",activation=tf.nn.relu)          \n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        concat_1 = tf.concat([conv_3x3,conv_4x4,conv_5x5],axis=3,name='concat_1')\n",
    "        \n",
    "        conv_5x5 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=5,padding='same',name=\"final_5x5\",activation=tf.nn.relu)\n",
    "        conv_4x4 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=4,padding='same',name=\"final_4x4\",activation=tf.nn.relu)\n",
    "        conv_3x3 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=3,padding='same',name=\"final_3x3\",activation=tf.nn.relu)\n",
    "        \n",
    "        concat_final = tf.concat([conv_5x5,conv_4x4,conv_3x3],axis=3,name='concat_final')\n",
    "        output = tf.layers.conv2d(inputs=concat_final,filters=3,kernel_size=1,padding='same',name='output')\n",
    "        \n",
    "        return output\n",
    "    \n",
    "        \n",
    "        \n",
    "def get_reveal_network_op(container_tensor):\n",
    "    \n",
    "    with tf.variable_scope('reveal_net'):\n",
    "        \n",
    "        with tf.variable_scope(\"3x3_conv_branch\"):\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=container_tensor,filters=50,kernel_size=3,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"2\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_3x3 = tf.layers.conv2d(inputs=conv_3x3,filters=50,kernel_size=3,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        with tf.variable_scope(\"4x4_conv_branch\"):\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=container_tensor,filters=50,kernel_size=4,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"2\",activation=tf.nn.relu)          \n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_4x4 = tf.layers.conv2d(inputs=conv_4x4,filters=50,kernel_size=4,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "\n",
    "        with tf.variable_scope(\"5x5_conv_branch\"):\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=container_tensor,filters=50,kernel_size=5,padding='same',name=\"1\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"2\",activation=tf.nn.relu)           \n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"3\",activation=tf.nn.relu)\n",
    "            conv_5x5 = tf.layers.conv2d(inputs=conv_5x5,filters=50,kernel_size=5,padding='same',name=\"4\",activation=tf.nn.relu)\n",
    "            \n",
    "        concat_1 = tf.concat([conv_3x3,conv_4x4,conv_5x5],axis=3,name='concat_1')\n",
    "        \n",
    "        conv_5x5 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=5,padding='same',name=\"final_5x5\",activation=tf.nn.relu)\n",
    "        conv_4x4 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=4,padding='same',name=\"final_4x4\",activation=tf.nn.relu)\n",
    "        conv_3x3 = tf.layers.conv2d(inputs=concat_1,filters=50,kernel_size=3,padding='same',name=\"final_3x3\",activation=tf.nn.relu)\n",
    "        \n",
    "        concat_final = tf.concat([conv_5x5,conv_4x4,conv_3x3],axis=3,name='concat_final')\n",
    "    \n",
    "    output = tf.layers.conv2d(inputs=concat_final,filters=3,kernel_size=1,padding='same',name='output')\n",
    "\n",
    "    return output\n",
    "\n",
    "def get_noise_layer_op(tensor,std=.1):\n",
    "    with tf.variable_scope(\"noise_layer\"):\n",
    "        return tensor + tf.random_normal(shape=tf.shape(tensor), mean=0.0, stddev=std, dtype=tf.float32) \n",
    "    \n",
    "def get_loss_op(secret_true,secret_pred,cover_true,cover_pred,beta=.5):\n",
    "    \n",
    "    with tf.variable_scope(\"losses\"):\n",
    "        beta = tf.constant(beta,name=\"beta\")\n",
    "        secret_mse = tf.losses.mean_squared_error(secret_true,secret_pred)\n",
    "        cover_mse = tf.losses.mean_squared_error(cover_true,cover_pred)\n",
    "        final_loss = cover_mse + beta*secret_mse\n",
    "        return final_loss , secret_mse , cover_mse \n",
    "\n",
    "def get_tensor_to_img_op(tensor):\n",
    "    with tf.variable_scope(\"\",reuse=True):\n",
    "        t = tensor*tf.convert_to_tensor([0.229, 0.224, 0.225]) + tf.convert_to_tensor([0.485, 0.456, 0.406])\n",
    "        return tf.clip_by_value(t,0,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prepare_training_graph(secret_tensor,cover_tensor,global_step_tensor):\n",
    "    \n",
    "    prep_output_op = get_prep_network_op(secret_tensor)\n",
    "    hiding_output_op = get_hiding_network_op(cover_tensor=cover_tensor,prep_output=prep_output_op)\n",
    "    noise_add_op = get_noise_layer_op(hiding_output_op)\n",
    "    reveal_output_op = get_reveal_network_op(noise_add_op)\n",
    "    \n",
    "    loss_op,secret_loss_op,cover_loss_op = get_loss_op(secret_tensor,reveal_output_op,cover_tensor,hiding_output_op,beta=BETA)\n",
    "\n",
    "    minimize_op = tf.train.AdamOptimizer(LEARNING_RATE).minimize(loss_op,global_step=global_step_tensor)\n",
    "    \n",
    "    tf.summary.scalar('loss', loss_op,family='train')\n",
    "    tf.summary.scalar('reveal_net_loss', secret_loss_op,family='train')\n",
    "    tf.summary.scalar('cover_net_loss', cover_loss_op,family='train')\n",
    "\n",
    "    tf.summary.image('secret',get_tensor_to_img_op(secret_tensor),max_outputs=1,family='train')\n",
    "    tf.summary.image('cover',get_tensor_to_img_op(cover_tensor),max_outputs=1,family='train')\n",
    "    tf.summary.image('hidden',get_tensor_to_img_op(hiding_output_op),max_outputs=1,family='train')\n",
    "    tf.summary.image('hidden_noisy',get_tensor_to_img_op(noise_add_op),max_outputs=1,family='train')\n",
    "    tf.summary.image('revealed',get_tensor_to_img_op(reveal_output_op),max_outputs=1,family='train')\n",
    "\n",
    "    merged_summary_op = tf.summary.merge_all()\n",
    "    \n",
    "    return minimize_op, merged_summary_op "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prepare_test_graph(secret_tensor,cover_tensor):\n",
    "    with tf.variable_scope(\"\",reuse=True):\n",
    "    \n",
    "        prep_output_op = get_prep_network_op(secret_tensor)\n",
    "        hiding_output_op = get_hiding_network_op(cover_tensor=cover_tensor,prep_output=prep_output_op)\n",
    "        reveal_output_op = get_reveal_network_op(hiding_output_op)\n",
    "        \n",
    "        loss_op,secret_loss_op,cover_loss_op = get_loss_op(secret_tensor,reveal_output_op,cover_tensor,hiding_output_op)\n",
    "\n",
    "        tf.summary.scalar('loss', loss_op,family='test')\n",
    "        tf.summary.scalar('reveal_net_loss', secret_loss_op,family='test')\n",
    "        tf.summary.scalar('cover_net_loss', cover_loss_op,family='test')\n",
    "\n",
    "        tf.summary.image('secret',get_tensor_to_img_op(secret_tensor),max_outputs=1,family='test')\n",
    "        tf.summary.image('cover',get_tensor_to_img_op(cover_tensor),max_outputs=1,family='test')\n",
    "        tf.summary.image('hidden',get_tensor_to_img_op(hiding_output_op),max_outputs=1,family='test')\n",
    "        tf.summary.image('revealed',get_tensor_to_img_op(reveal_output_op),max_outputs=1,family='test')\n",
    "\n",
    "        merged_summary_op = tf.summary.merge_all()\n",
    "\n",
    "        return merged_summary_op "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prepare_deployment_graph(secret_tensor,cover_tensor,covered_tensor):\n",
    "    with tf.variable_scope(\"\",reuse=True):\n",
    "\n",
    "        prep_output_op = get_prep_network_op(secret_tensor)\n",
    "        hiding_output_op = get_hiding_network_op(cover_tensor=cover_tensor,prep_output=prep_output_op)\n",
    "\n",
    "        reveal_output_op = get_reveal_network_op(covered_tensor)\n",
    "\n",
    "        return hiding_output_op ,  reveal_output_op"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "sess = tf.InteractiveSession(graph=tf.Graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "secret_tensor = tf.placeholder(shape=[None,224,224,3],dtype=tf.float32,name=\"input_prep\")\n",
    "cover_tensor = tf.placeholder(shape=[None,224,224,3],dtype=tf.float32,name=\"input_hide\")\n",
    "global_step_tensor = tf.Variable(0, trainable=False, name='global_step')\n",
    "\n",
    "train_op , summary_op = prepare_training_graph(secret_tensor,cover_tensor,global_step_tensor)\n",
    "\n",
    "writer = tf.summary.FileWriter(join(LOGS_Path,EXP_NAME),sess.graph)\n",
    "\n",
    "test_op = prepare_test_graph(secret_tensor,cover_tensor)\n",
    "\n",
    "covered_tensor = tf.placeholder(shape=[None,224,224,3],dtype=tf.float32,name=\"deploy_covered\")\n",
    "deploy_hide_image_op , deploy_reveal_image_op = prepare_deployment_graph(secret_tensor,cover_tensor,covered_tensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "saver = tf.train.Saver(max_to_keep=1)\n",
    "sess.run(tf.global_variables_initializer())\n",
    "# saver.restore(sess,join(CHECKPOINTS_PATH,EXP_NAME))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "total_steps = len(files_list)//BATCH_SIZE + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for ep in range(100):\n",
    "    for step in range(total_steps):\n",
    "        covers,secrets = get_img_batch(files_list=files_list,batch_size=BATCH_SIZE)\n",
    "        sess.run([train_op],feed_dict={\"input_prep:0\":secrets,\"input_hide:0\":covers})\n",
    "        \n",
    "        if step % 10 ==0 :\n",
    "            \n",
    "            summary,global_step = sess.run([summary_op,global_step_tensor],feed_dict={\"input_prep:0\":secrets,\"input_hide:0\":covers})\n",
    "            writer.add_summary(summary,global_step)\n",
    "            \n",
    "        if step % 100 ==0 :\n",
    "            \n",
    "            covers,secrets = get_img_batch(files_list=files_list,batch_size=1)\n",
    "            summary,global_step = sess.run([test_op,global_step_tensor],feed_dict={\"input_prep:0\":secrets,\"input_hide:0\":covers})\n",
    "            writer.add_summary(summary,global_step)\n",
    "\n",
    "    \n",
    "    save_path = saver.save(sess, join(CHECKPOINTS_PATH,EXP_NAME+\".chkp\"),global_step=global_step)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# sess.close()\n",
    "\n",
    "writer.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "covers,secrets = get_img_batch(files_list=files_list,batch_size=1)\n",
    "\n",
    "cover = covers.squeeze()\n",
    "secret = secrets.squeeze()\n",
    "plt.imshow(denormalize_batch(cover))\n",
    "plt.show()\n",
    "plt.imshow(denormalize_batch(secret))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hidden = sess.run(deploy_hide_image_op,feed_dict={'input_prep:0':secrets,'input_hide:0':covers})\n",
    "\n",
    "plt.imshow(denormalize_batch(hidden.squeeze()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "revealed = sess.run(deploy_reveal_image_op,feed_dict={'deploy_covered:0':hidden})\n",
    "\n",
    "plt.imshow(denormalize_batch(revealed.squeeze()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.imshow(np.clip(hiding_output.squeeze(),0,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hiding_network_output = sess.run([hiding_output_op],\n",
    "                                  feed_dict={secret_tensor:secrets,cover_tensor:covers})[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# plt.imshow(np.clip(hiding_network_output[0],0,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# join(\"OK\",\".OK\",\".OK\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# covers,secrets = get_img_batch(files_list=files_list,batch_size=BATCH_SIZE)\n",
    "\n",
    "# type(secrets)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# files_list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# image_str = tf.placeholder(tf.string)\n",
    "# im_tf = tf.image.decode_image(image_str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# cover_imgs = []\n",
    "# hidden_imgs = []\n",
    "# hidden_noisy = []\n",
    "# reveal_imgs = []\n",
    "# secret_imgs = []\n",
    "\n",
    "\n",
    "# count = 0\n",
    "# for e in tf.train.summary_iterator(join(LOGS_Path,'beta_0.25','events.out.tfevents.1516061354.pcvirus')):\n",
    "#     for v in e.summary.value:\n",
    "#         if v.tag == 'train/train/cover/image':\n",
    "#             output = im_tf.eval(feed_dict={image_str:v.image.encoded_image_string})\n",
    "#             cover_imgs.append(output)\n",
    "            \n",
    "#         if v.tag == 'train/train/hidden/image':\n",
    "#             output = im_tf.eval(feed_dict={image_str:v.image.encoded_image_string})\n",
    "#             hidden_imgs.append(output)\n",
    "        \n",
    "#         if v.tag == 'train/train/hidden_noisy/image':\n",
    "#             output = im_tf.eval(feed_dict={image_str:v.image.encoded_image_string})\n",
    "#             hidden_noisy.append(output)\n",
    "            \n",
    "#         if v.tag == 'train/train/revealed/image':\n",
    "#             output = im_tf.eval(feed_dict={image_str:v.image.encoded_image_string})\n",
    "#             reveal_imgs.append(output)\n",
    "            \n",
    "#         if v.tag == 'train/train/secret/image':\n",
    "#             output = im_tf.eval(feed_dict={image_str:v.image.encoded_image_string})\n",
    "#             secret_imgs.append(output)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
